#ifndef _MC_SHARE_
#define _MC_SHARE_

typedef unsigned int uint;

#include "tables.h"
#include "ShareDef.h"
//#include "..\Modeling\CUDADataStruct.h"
#include "..\..\common\CUDA\cutil\inc\cutil.h"
#include "..\..\common\CUDA\cudpp\inc\cudpp.h"
#include "..\..\common\CUDA\cutil\inc\cutil_math.h"



float isoValue = 0.0f;
float dIsoValue = 0.005f;

CUDPPHandle scanplan;

float *d_volume = 0;

uint* d_triTable = 0;


////////////////////////////////////////////////////////////////////////////////
// initialize marching cubes
////////////////////////////////////////////////////////////////////////////////
__constant__ float* dFuncData = 0;
__constant__ int* dPatchIndex = 0;
//extern ABSSURF_SHARE_INFO asi;


//Compact volumeData
//float* dVolumeData = 0;
//texture<int, 1, cudaReadModeElementType> volume2Tex;

texture<uint, 1, cudaReadModeElementType> triTex;

// volume data
texture<float, 1, cudaReadModeElementType> volumeTex;

// sample volume data set at a point
__device__
float sampleVolume(float *data, uint3 p, uint3 volumeSizeShift)
{
	//girdSize is the actual voxel number,
	//p.x = min(p.x, vertNumber.x-1);
	//but not: p.x = min(p.x, gridSize.x-1);
	//And, volumeSizeShift = gridSize+1; so elimination min();
    //p.x = min(p.x, gridSize.x);
    //p.y = min(p.y, gridSize.y);
    //p.z = min(p.z, gridSize.z);
    uint i = p.x*volumeSizeShift.x + p.y*volumeSizeShift.y + p.z*volumeSizeShift.z;
//    return (float) data[i] / 255.0f;
    return tex1Dfetch(volumeTex, i);
}

// compute position in 3d grid from 1d index
// only works for power of 2 sizes
__device__
uint3 calcGridPos(uint i, uint3 volumeSizeShift, uint3 gridSizeMask)
{
    uint3 gridPos;
    gridPos.x = i & gridSizeMask.x;
    gridPos.y = (i >> volumeSizeShift.y) & gridSizeMask.y;
    gridPos.z = (i >> volumeSizeShift.z) & gridSizeMask.z;
    return gridPos;
}

__device__
uint3 calcGridPos(uint i, uint3 gridSize)
{
    uint3 gridPos;
	uint zShift = gridSize.x*gridSize.y;
	uint yShift = gridSize.x;
    gridPos.z = i / zShift;
    gridPos.y = i % zShift;
    gridPos.x = gridPos.y % yShift;
    gridPos.y = gridPos.y / yShift;    
    return gridPos;
}

#endif